"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports._setData = exports.createContext = void 0;
var event_1 = require("./event");
var utils_1 = require("./utils");
var shared_1 = require("./shared");
var reactive_1 = require("./reactive");
var diff_1 = require("./diff");
/**
 * 创建context对象
 * @param target {CurrentInstance} 小程序 this 实例
 * @return {IContext} context 对象
 */
function createContext() {
    // 封装setData方法
    function setData(binding) {
        var _this = this;
        if (!binding)
            return;
        Object.keys(binding).map(function (key) {
            var value = binding[key];
            if (utils_1.isFunction(value))
                return _this[key] = value;
            _setData.call(_this, key, shared_1.deepToRaw(value));
            // 添加监听
            dataWatch.call(_this, key, value);
        });
    }
    return {
        setData: setData.bind(this),
        event: event_1.mitt()
    };
}
exports.createContext = createContext;
/**
 * 添加data监听
 * @param key {String} 键值
 * @param value {unknown} 值
 */
function dataWatch(key, value) {
    var _this = this;
    // 非对象不监听
    if (!utils_1.isObject(value))
        return;
    // 添加监听
    reactive_1.effect(function () {
        _setData.call(_this, key, shared_1.deepToRaw(value));
    }, true);
}
var hasPromise = new Map(); // 当前任务列队是有已有Promise
var allData = new Map(); // 所有setData的值
/**
 * 修改data值
 * @param data {Object} 要更新的值
 */
function _setData(key, data) {
    var _a, _b;
    var _this = this;
    var _allData = allData.get(this) || {};
    var _data = diff_1.diff((_a = {}, _a[key] = data, _a), (_b = {}, _b[key] = this.data[key], _b));
    for (var k in _data) {
        for (var j in _allData) {
            new RegExp('^' + k + '\\[\\d+\\].*$').test(j) && delete _allData[j];
        }
    }
    allData.set(this, Object.assign(_allData, _data));
    if (!hasPromise.get(this)) {
        hasPromise.set(this, true);
        Promise.resolve().then(function () {
            (Object.getOwnPropertyNames(allData.get(_this)).length !== 0)
                && _this.setData(allData.get(_this));
            allData.delete(_this);
            hasPromise.delete(_this);
        });
    }
}
exports._setData = _setData;
